Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce integration with TGE energy sensor #335

Conversation

KrzysztofHajdamowicz
Copy link
Contributor

Polish electricity sellers calculate prices based on TGE Fixing 1.
TGE stands for "Towarowa Giełda Energii" (https://www.tge.pl/) and is a most important exchange market for electricity in Poland.

@PiotrMachowski created excellent HA integration that provides price table from that exchange.
https://github.com/PiotrMachowski/Home-Assistant-custom-components-TGE

I tested this changes using my production HA instance.

@KrzysztofHajdamowicz KrzysztofHajdamowicz marked this pull request as draft October 30, 2024 23:31
@KrzysztofHajdamowicz
Copy link
Contributor Author

I've found unexpected errors in my second HA instance:

2024-10-31 00:23:39.456 DEBUG (MainThread) [custom_components.ev_smart_charging] async_setup_entry
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.sensor] EVSmartCharging.sensor.py
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.sensor] EVSmartChargingSensor.__init__()
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.sensor] EVSmartChargingSensor.__init__()
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.entity] entity_id = sensor.ev_smart_charging_charging
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.sensor] EVSmartChargingSensorStatus.__init__()
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.sensor] EVSmartChargingSensor.__init__()
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.entity] entity_id = sensor.ev_smart_charging_status
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.sensor] EVSmartChargingSensorChargingCurrent.__init__()
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.sensor] EVSmartChargingSensor.__init__()
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.entity] entity_id = sensor.ev_smart_charging_charging_current
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.sensor] EVSmartChargingSensorSolarStatus.__init__()
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.sensor] EVSmartChargingSensor.__init__()
2024-10-31 00:23:39.563 DEBUG (MainThread) [custom_components.ev_smart_charging.entity] entity_id = sensor.ev_smart_charging_solar_status
2024-10-31 00:23:39.565 DEBUG (MainThread) [custom_components.ev_smart_charging.coordinator] EVSmartChargingCoordinator.update_sensors()
2024-10-31 00:23:39.565 DEBUG (MainThread) [custom_components.ev_smart_charging.coordinator] entity_id = None
2024-10-31 00:23:39.565 DEBUG (MainThread) [custom_components.ev_smart_charging.coordinator] new_state = None
2024-10-31 00:23:39.565 ERROR (MainThread) [custom_components.ev_smart_charging.coordinator] Price sensor not valid
2024-10-31 00:23:39.565 ERROR (MainThread) [custom_components.ev_smart_charging.coordinator] Price state: <state sensor.tge_fixing_1_rate=50.578; state_class=measurement, prices_today=[{'time': datetime.datetime(2024, 10, 31, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 50.578}, {'time': datetime.datetime(2024, 10, 31, 1, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 48.227}, {'time': datetime.datetime(2024, 10, 31, 2, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 48.227}, {'time': datetime.datetime(2024, 10, 31, 3, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 48.693}, {'time': datetime.datetime(2024, 10, 31, 4, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 49.457}, {'time': datetime.datetime(2024, 10, 31, 5, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 54.891}, {'time': datetime.datetime(2024, 10, 31, 6, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 65.189}, {'time': datetime.datetime(2024, 10, 31, 7, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 70.945}, {'time': datetime.datetime(2024, 10, 31, 8, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 67.821}, {'time': datetime.datetime(2024, 10, 31, 9, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 62.154}, {'time': datetime.datetime(2024, 10, 31, 10, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 52.901}, {'time': datetime.datetime(2024, 10, 31, 11, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 47.519}, {'time': datetime.datetime(2024, 10, 31, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 43.071}, {'time': datetime.datetime(2024, 10, 31, 13, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 44.736}, {'time': datetime.datetime(2024, 10, 31, 14, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 49.211}, {'time': datetime.datetime(2024, 10, 31, 15, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 54.623}, {'time': datetime.datetime(2024, 10, 31, 16, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 66.694}, {'time': datetime.datetime(2024, 10, 31, 17, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 68.78}, {'time': datetime.datetime(2024, 10, 31, 18, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 65.399}, {'time': datetime.datetime(2024, 10, 31, 19, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 59.64}, {'time': datetime.datetime(2024, 10, 31, 20, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 48.881}, {'time': datetime.datetime(2024, 10, 31, 21, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 41.338}, {'time': datetime.datetime(2024, 10, 31, 22, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 38.386}, {'time': datetime.datetime(2024, 10, 31, 23, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 24.84}], prices_tomorrow=[], prices=[{'time': datetime.datetime(2024, 10, 31, 0, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 50.578}, {'time': datetime.datetime(2024, 10, 31, 1, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 48.227}, {'time': datetime.datetime(2024, 10, 31, 2, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 48.227}, {'time': datetime.datetime(2024, 10, 31, 3, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 48.693}, {'time': datetime.datetime(2024, 10, 31, 4, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 49.457}, {'time': datetime.datetime(2024, 10, 31, 5, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 54.891}, {'time': datetime.datetime(2024, 10, 31, 6, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 65.189}, {'time': datetime.datetime(2024, 10, 31, 7, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 70.945}, {'time': datetime.datetime(2024, 10, 31, 8, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 67.821}, {'time': datetime.datetime(2024, 10, 31, 9, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 62.154}, {'time': datetime.datetime(2024, 10, 31, 10, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 52.901}, {'time': datetime.datetime(2024, 10, 31, 11, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 47.519}, {'time': datetime.datetime(2024, 10, 31, 12, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 43.071}, {'time': datetime.datetime(2024, 10, 31, 13, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 44.736}, {'time': datetime.datetime(2024, 10, 31, 14, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 49.211}, {'time': datetime.datetime(2024, 10, 31, 15, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 54.623}, {'time': datetime.datetime(2024, 10, 31, 16, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 66.694}, {'time': datetime.datetime(2024, 10, 31, 17, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 68.78}, {'time': datetime.datetime(2024, 10, 31, 18, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 65.399}, {'time': datetime.datetime(2024, 10, 31, 19, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 59.64}, {'time': datetime.datetime(2024, 10, 31, 20, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 48.881}, {'time': datetime.datetime(2024, 10, 31, 21, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 41.338}, {'time': datetime.datetime(2024, 10, 31, 22, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 38.386}, {'time': datetime.datetime(2024, 10, 31, 23, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=3600))), 'price': 24.84}], unit_of_measurement=gr/kWh, icon=mdi:cash, friendly_name=TGE Fixing 1 Rate @ 2024-10-31T00:23:36.167178+01:00>
2024-10-31 00:23:39.567 DEBUG (MainThread) [custom_components.ev_smart_charging.helpers.coordinator] charging_hours = 2
2024-10-31 00:23:39.567 DEBUG (MainThread) [custom_components.ev_smart_charging.helpers.coordinator] ready_hour = 2024-10-31 07:00:00+00:00
2024-10-31 00:23:39.567 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up ev_smart_charging platform for sensor
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 361, in _async_setup_platform
    await asyncio.shield(awaitable)
  File "/config/custom_components/ev_smart_charging/sensor.py", line 33, in async_setup_entry
    await coordinator.add_sensor(sensors)
  File "/config/custom_components/ev_smart_charging/coordinator.py", line 580, in add_sensor
    await self.update_sensors()
  File "/config/custom_components/ev_smart_charging/coordinator.py", line 981, in update_sensors
    self.scheduler.create_base_schedule(scheduling_params, self.raw_two_days)
  File "/config/custom_components/ev_smart_charging/helpers/coordinator.py", line 460, in create_base_schedule
    lowest_hours = get_lowest_hours(
                   ^^^^^^^^^^^^^^^^^
  File "/config/custom_components/ev_smart_charging/helpers/coordinator.py", line 212, in get_lowest_hours
    return get_lowest_hours_non_continuous(start_hour, ready_hour, raw_two_days, hours)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/ev_smart_charging/helpers/coordinator.py", line 228, in get_lowest_hours_non_continuous
    for item in raw_two_days.get_raw():
                ^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get_raw'

Maybe it's somehow related to fact that prices for tomorrow are still not published yet?

image
Graph shows TGE prices overlayed with charging slot calculated by ENTSO-E integration I've used as alternative pricing source. Last known timeslot if for 23:00-00:00 time

@KrzysztofHajdamowicz KrzysztofHajdamowicz marked this pull request as ready for review October 31, 2024 14:06
@KrzysztofHajdamowicz
Copy link
Contributor Author

OK, with a debug session with @PiotrMachowski we've managed to write code that works between TGE and EV Smart Charging.

Copy link

codecov bot commented Jan 4, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.67%. Comparing base (dfd4df1) to head (5f7636b).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #335      +/-   ##
==========================================
+ Coverage   98.65%   98.67%   +0.01%     
==========================================
  Files          14       14              
  Lines        1791     1809      +18     
==========================================
+ Hits         1767     1785      +18     
  Misses         24       24              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jonasbkarlsson
Copy link
Owner

When this issue is (PiotrMachowski/Home-Assistant-custom-components-TGE#15) is fixed, I can merge this PR to the main branch.

@PiotrMachowski
Copy link

@jonasbkarlsson I have fixed this issue. To be honest it was not a big one, it occurred only during the first day if you have configured the integration after 2PM. After that data was cached and restored on HA restart.

@jonasbkarlsson jonasbkarlsson force-pushed the feature/tge-integration branch from 33d8235 to 5f7636b Compare January 5, 2025 14:22
@jonasbkarlsson jonasbkarlsson merged commit 42b6dc9 into jonasbkarlsson:main Jan 5, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants